#include "scheduler.cpp"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int NUM_OF_EXPAND[] = {0, 100};
const int MAX_OF_PHY_MAC = 100000;
const double MAX_SCORE = 200.0;
const double SCORE_OF_BASLINE = 200.0 * 0.6;

struct InteractiveSystem {
  int n;
  int total_vcpu;
  int total_mem;
  int num_of_ins;
  vector<int> used_vcpu;
  vector<int> used_mem;
  vector<int> id_to_pos;
  vector<int> id_to_vcpu;
  vector<int> id_to_mem;
  Scheduler scheduler;

  void addVM(int id, int vcpu, int mem) {
    assert(id == (int)id_to_pos.size());
    id_to_pos.push_back(-1);
    id_to_vcpu.push_back(vcpu);
    id_to_mem.push_back(mem);
  }

  bool create(int id, int pos, int vcpu, int mem) {
    if (pos < 0 || pos >= (int)used_vcpu.size()) {
      return false;
    }
    if (used_vcpu[pos] + vcpu > total_vcpu || used_mem[pos] + mem > total_mem) {
      return false;
    }
    id_to_pos[id] = pos;
    used_vcpu[pos] += vcpu;
    used_mem[pos] += mem;
    return true;
  }

  void remove(int id) {
    int pos = id_to_pos[id];
    int vcpu = id_to_vcpu[id];
    int mem = id_to_mem[id];
    used_vcpu[pos] -= vcpu;
    used_mem[pos] -= mem;
  }

  void init(string file_name) {
    freopen(file_name.c_str(), "r", stdin);
    cin >> n >> total_vcpu >> total_mem;
    cin >> num_of_ins;
    for (int i = 0; i < n; i++) {
      used_vcpu.push_back(0);
    }
    used_mem.resize(n, 0);
    scheduler.init(n, total_vcpu, total_mem);
  }

  bool runOnce() {
    int id;
    char ins_name[10];
    scanf("%s %d", ins_name, &id);
    bool is_success = true;
    if (ins_name[0] == 'C') {
      int vcpu;
      int mem;
      scanf("%d %d", &vcpu, &mem);
      pair<int, int> res = scheduler.create(id, vcpu, mem);
      if (res.second < NUM_OF_EXPAND[0] || res.second > NUM_OF_EXPAND[1]) {
        return false;
      }
      int pos = res.first;
      for (int i = 0; i < res.second; i++) {
        n++;
        if (n > MAX_OF_PHY_MAC) {
          return false;
        }
        used_vcpu.push_back(0);
        used_mem.push_back(0);
      }
      id_to_pos.push_back(0);
      id_to_vcpu.push_back(vcpu);
      id_to_mem.push_back(mem);
      is_success = create(id, pos, vcpu, mem);
    } else {
      scheduler.remove(id);
      remove(id);
    }
    return is_success;
  }

  int getNumOfMachines() {
    bool is_success = true;
    // cout << "num_of_ins:" << num_of_ins << endl;
    for (int i = 0; i < num_of_ins; i++) {
      if (!runOnce()) {
        is_success = false;
        break;
      }
    }
    // cout << "yy: is_success=" << (is_success ? (int)used_vcpu.size() : -1) <<
    // endl;
    return is_success ? (int)used_vcpu.size() : -1;
  }

  void printState() {
    cout << "numOfTotalMachines: " << n << endl;
    cout << "totalVcpu: " << total_vcpu << "; totalMem: " << total_mem << endl;
    for (int i = 0; i < n; i++) {
      cout << "used_vcpu[" << i << "]: " << used_vcpu[i];
      cout << "; used_mem[" << i << "]: " << used_mem[i] << endl;
    }
  }
};

int main() {
  string mode = "GEN_SCH_SCORE";
  if (mode.find("GEN_SCH_SCORE") != string::npos) {
    string score_path = "../final_score.txt";
    freopen(score_path.c_str(), "w", stdout);
    int n_tests = 20;
    double total_score = 0;
    vector<double> score_list;
    for (int i = 1; i <= n_tests; i++) {
      clog << "test case #" << i << ": ";
      InteractiveSystem inter_sys;
      string file_name = string("../data/") + to_string(i) + string(".in");
      inter_sys.init(file_name);
      int res = inter_sys.getNumOfMachines();
      file_name =
          string("../data/") + "baseline_" + string(to_string(i)) + ".out";
      freopen(file_name.c_str(), "r", stdin);
      int baseline;
      cin >> baseline;
      // cout << "case " << i << ": " << baseline / res * 60 << endl;
      double score = 0.0;
      if (res != -1)
        score = min(MAX_SCORE, 1.0 * baseline / res * SCORE_OF_BASLINE);
      score_list.push_back(score);
      total_score += score;
      clog << score << endl;
    }
    clog << "Final Score: " << total_score / score_list.size() << endl;
    printf("Final Score: %.2f\n", total_score / score_list.size());
    for (int i = 0; i < score_list.size(); i++) {
      printf("Score of Test Case #%d: %.2f\n", i + 1, score_list[i]);
    }
  }
  return 0;
}